package com.happycat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.happycat.Pagination;
import com.happycat.ResponseHeaderModel;
import com.happycat.ResponseModel;
import com.happycat.SysContants;
import com.happycat.base.R;
import com.happycat.base.exception.RestApiException;
import com.happycat.config.Audience;
import com.happycat.config.HappyCatSecurity;
import com.happycat.mapper.UserAccountMapper;
import com.happycat.mobile.dto.LoginDto;
import com.happycat.mobile.enums.ShortMessageEnum;
import com.happycat.mobile.model.*;
import com.happycat.mobile.service.*;
import com.happycat.utils.AesUtils;
import com.happycat.utils.AgeUtils;
import com.happycat.utils.JwtTokenUtil;
import com.happycat.utils.ResponseModelUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * Module: UserAccount.java
 * 
 * @author liaoyong
 * @since JDK 1.8
 * @version 1.0
 * @date 2020-07-14
 * @Descriptions:
 */
@Service
@Slf4j
public class UserAccountServiceImpl extends ServiceImpl<UserAccountMapper, UserAccount> implements UserAccountService {


	@Autowired
	private GenerateIdService generateIdService;
	@Autowired
	private AccountRoleMappingService accountRoleMappingService;
	@Autowired
	private Audience audience;
	@Autowired
	private UserLoginLogService userLoginLogService;
	@Autowired
	private HappyCatSecurity happyCatSecurity;
	@Autowired
	private UserShortMessageService userShortMessageService;

	@Autowired
	private AccountRoleService accountRoleService;
	
	@Autowired
	private UserManitoApplyService userManitoApplyService ;
	@Autowired
	private UserSettingService userSettingService;
	
	@Autowired
	private CatAppSettingService catAppSettingService;

	@Autowired
    private UserBalancePetValueDetailService balancePetValueDetailService;

	@Autowired
    private UserExperienceService userExperienceService;

	public ResponseModel<UserAccount> selectOne(UserAccount userAccount) {
		Wrapper<UserAccount> queryWrapper = new QueryWrapper<>(userAccount);
		ResponseModel<UserAccount> responseModel = new ResponseModel<>();
		responseModel.setCode(SysContants.SYS_SUCCESS_CODE);
		responseModel.setMessage("查询成功");
		QueryWrapper<UserManitoApply> queryWrapperManito = new QueryWrapper<UserManitoApply>();	
		queryWrapperManito.eq("account_id", userAccount.getId());
		queryWrapperManito.eq("status", SysContants.YES);
		List<UserManitoApply> userManitoApplyList = userManitoApplyService.list(queryWrapperManito);
		UserAccount userAccountResult = getOne(queryWrapper);
		if(userManitoApplyList != null && userManitoApplyList.size() > 0) {
			userAccountResult.setManito(SysContants.YES);
		}else {
			userAccountResult.setManito(SysContants.NO);
		}
		
		responseModel.setData(userAccount);
		return responseModel;

	}

	public ResponseHeaderModel add(UserAccount userAccount) {
		ResponseHeaderModel responseHeaderModel = new ResponseHeaderModel();
        //生成声网userId
        userAccount.setImUserId(UUID.randomUUID().toString());
		boolean result = save(userAccount);
		if (result) {
			responseHeaderModel.setCode(SysContants.SYS_SUCCESS_CODE);
			responseHeaderModel.setMessage("新增成功");
		} else {
			responseHeaderModel.setCode(SysContants.SYS_FAIL_CODE);
			responseHeaderModel.setMessage("新增失败");
		}
		return responseHeaderModel;
	}

	public ResponseHeaderModel modify(UserAccount userAccount) {
		ResponseHeaderModel responseHeaderModel = new ResponseHeaderModel();
		// 查询用户是否存在
		UserAccount userAccountParam = new UserAccount();
		userAccountParam.setAccountName(userAccount.getAccountName());
		Wrapper<UserAccount> queryWrapper = new QueryWrapper<>(userAccountParam);
		UserAccount userAccountResult = getOne(queryWrapper);
		if (userAccountResult == null) {
			return ResponseModelUtils.fail("用户不存在，请前往注册！");
		}
		/*
		 * if (StringUtils.isNotBlank(userAccount.getPassword())) {// 修改密码 String
		 * paramPassword = userAccount.getPassword(); String decryptPassword =
		 * AesUtils.decrypt(paramPassword, happyCatSecurity.getAesKey());
		 * userAccount.setPassword(AesUtils.encrypt(decryptPassword,
		 * happyCatSecurity.getStageBackAesKey())); }
		 */
		if(StringUtils.isNotBlank(userAccount.getBirthDay())) {
			userAccount.setAge(AgeUtils.getAgeFromBirthTime(userAccount.getBirthDay()));
		}
		
		userAccount.setId(userAccountResult.getId());
		boolean result = updateById(userAccount);
		if (result) {
			return ResponseModelUtils.success("修改成功");			
		} else {
			return ResponseModelUtils.fail("修改失败");
		}
	}

	public ResponseModel<Page<UserAccount>> pageList(Pagination<UserAccount>page) {
		ResponseModel<Page<UserAccount>> responseModel = new ResponseModel<>();
		responseModel.setCode(SysContants.SYS_SUCCESS_CODE);
		responseModel.setMessage("查询成功");
		responseModel.setData(this.baseMapper.pageList(page,new QueryWrapper<UserAccount>(page.getEntity())));
		return responseModel;
	}

	
	public UserAccount getAccountMappingRoleList(UserAccount userAccount) {

		return baseMapper.getAccountMappingRoleList(userAccount);
	}

	@Transactional
	public ResponseModel<UserAccount> login(LoginDto loginDto) {
		if (loginDto == null) {
			return ResponseModelUtils.fail("请输入手机号！", null);
		}
		if (StringUtils.isBlank(loginDto.getAccountName())) {
			return ResponseModelUtils.fail("请输入手机号！", null);
		}
		UserAccount userAccount = BeanUtil.copyProperties(loginDto, UserAccount.class);

		String encryptAccountName = loginDto.getAccountName();//加密的手机号
		try {
			userAccount.setAccountName(AesUtils.decrypt(loginDto.getAccountName(), happyCatSecurity.getAesKey()));
		}catch(Exception e) {
			return ResponseModelUtils.fail("账号不正确！", null);
		}
		
		// 查询用户是否存在
		UserAccount userAccountParam = new UserAccount();
		userAccountParam.setAccountName(userAccount.getAccountName());
		UserAccount userAccountResult = getAccountMappingRoleList(userAccountParam);
//		if(1 == loginDto.getLoginType()) {//未注册用户登录
//			UserShortMessage userShortMessage = new UserShortMessage();
//			userShortMessage.setPhone(encryptAccountName);
//			userShortMessage.setMessage(loginDto.getVerifyCode());
//			ResponseModel<String> userShortMessageRes  = userShortMessageService.checkVerifyCode(userShortMessage);
//			if(SysContants.SYS_SUCCESS_CODE == userShortMessageRes.getCode()) {
//				return ResponseModelUtils.success("验证成功", null);
//			}else {
//				return ResponseModelUtils.fail(userShortMessageRes.getMessage(), null);
//			}
//		}
		if(userAccountResult == null) {
		    if(loginDto.getLoginType()!=SysContants.LOGIN_TYPE_CODE){
			    return ResponseModelUtils.fail("登录失败,账号不存在", userAccountResult);
            }
		    if(loginDto.getIsForceRegister()!=1){
			    return ResponseModelUtils.fail("登录失败,账号不存在", userAccountResult);
            }
		}else
		    userAccount.setId(userAccountResult.getId());

		// 设置用户角色
		userAccount.setAccountRoleList(userAccountResult.getAccountRoleList());

		if(SysContants.LOGIN_TYPE_CODE == loginDto.getLoginType()) {//验证码登录
		    if(StrUtil.isBlank(loginDto.getVerifyCode())){
		        throw new RestApiException(R.fail(-1, "验证码不能为空"));
            }

			UserShortMessage userShortMessage = new UserShortMessage();
			userShortMessage.setPhone(encryptAccountName);
			userShortMessage.setMessage(loginDto.getVerifyCode());
			userShortMessage.setTemplateCode(ShortMessageEnum.login.getCode());//登录模板
			ResponseModel<String> userShortMessageRes  = userShortMessageService.checkVerifyCode(userShortMessage);

			if(SysContants.SYS_SUCCESS_CODE == userShortMessageRes.getCode()) {
                if(userAccountResult==null && loginDto.getIsForceRegister()==1){
                    //强制注册账户
                    //设置初始化密钥
                    userAccount.setPassword(AesUtils.encrypt(RandomUtil.randomString(6),
                            happyCatSecurity.getStageBackAesKey()));

                    //生成声网userId
                    userAccount.setImUserId(UUID.randomUUID().toString().replace("_", ""));
                    //保存
                    save(userAccount);

                    //发送注册成功短信
//                    UserShortMessage registSms = new UserShortMessage();
//                    registSms.setPhone(loginDto.getAccountName());
//                    registSms.setTemplateCode(ShortMessageEnum.register.getCode());
//                    userShortMessageService.sendMessage(registSms);
                }

				UserLoginLog userLoginLog = new UserLoginLog();
				userLoginLog.setId(generateIdService.nextDefaultSerialNumber());
				userLoginLog.setAccountId(userAccountResult.getId());
				userLoginLog.setDevice(loginDto.getDevice());
				userLoginLog.setLoginType(SysContants.LOGIN_TYPE_CODE);
				userLoginLog.setCreateTime(new Date());
				userLoginLog.setLoginResult("登录成功");
				userLoginLogService.save(userLoginLog);
				userAccount.setPassword(null);
				userAccount.setToken(JwtTokenUtil.createJWT(userAccount, audience));

				return ResponseModelUtils.success("登录成功", userAccount);
			}else {
				UserLoginLog userLoginLog = new UserLoginLog();
				userLoginLog.setId(generateIdService.nextDefaultSerialNumber());
				userLoginLog.setAccountId(userAccountResult.getId());
				userLoginLog.setDevice(loginDto.getDevice());
				userLoginLog.setLoginType(SysContants.LOGIN_TYPE_CODE);
				userLoginLog.setCreateTime(new Date());
				userLoginLog.setLoginResult("验证失败");
				userLoginLog.setResultReason(userShortMessageRes.getMessage());
				userLoginLogService.save(userLoginLog);
				return ResponseModelUtils.fail(userShortMessageRes.getMessage(), null); 
			} 			
		}
		
		if (SysContants.LOGIN_TYPE_PASSWORD == loginDto.getLoginType()) {// 密码登录
			if (StringUtils.isBlank(loginDto.getPassword())) {
				return ResponseModelUtils.fail("登录密码不能为空！", null);
			}	
			
			if (StringUtils.compare(AesUtils.decrypt(loginDto.getPassword(), happyCatSecurity.getAesKey()),
					AesUtils.decrypt(userAccountResult.getPassword(), happyCatSecurity.getStageBackAesKey())) == 0) {
			
				UserLoginLog userLoginLog = new UserLoginLog();
				userLoginLog.setId(generateIdService.nextDefaultSerialNumber());
				userLoginLog.setAccountId(userAccountResult.getId());
				userLoginLog.setDevice(loginDto.getDevice());
				userLoginLog.setLoginType(SysContants.LOGIN_TYPE_CODE);
				userLoginLog.setCreateTime(new Date());
				userLoginLog.setLoginResult("登成功");
				userLoginLogService.save(userLoginLog);//保存登录日志				
				userAccount.setPassword(null);
				userAccount.setToken(JwtTokenUtil.createJWT(userAccount, audience));
				return ResponseModelUtils.success("登录成功", userAccount);
			} else {
				UserLoginLog userLoginLog = new UserLoginLog();
				userLoginLog.setId(generateIdService.nextDefaultSerialNumber());
				userLoginLog.setAccountId(userAccountResult.getId());
				userLoginLog.setDevice(loginDto.getDevice());
				userLoginLog.setLoginType(SysContants.LOGIN_TYPE_CODE);
				userLoginLog.setCreateTime(new Date());
				userLoginLog.setLoginResult("登录失败");
				userLoginLog.setResultReason("登录密码不正确！");
				userLoginLogService.save(userLoginLog); 
				return ResponseModelUtils.fail("登录密码不正确！",null);
			}
		}
		
		return ResponseModelUtils.success("登录类型不支持！",null);

	}
	
	public UserAccount register(UserAccount userAccount) {
		Long accountId = generateIdService.nextDefaultSerialNumber();
		userAccount.setId(accountId);
		userAccount.setCreateTime(new Date());
		userAccount.setStatus(SysContants.USER_STATUS_REGISTER);
        //生成声网userId
        userAccount.setImUserId(UUID.randomUUID().toString().replace("_", ""));
		save(userAccount);// 保存账号密码
		// 查询角色
		AccountRole accountRole = accountRoleService.getById(1);
		List<AccountRole> roleList = new ArrayList<AccountRole>();
		roleList.add(accountRole);
		userAccount.setAccountRoleList(roleList);
		//保存用户系统设置
		List<CatAppSetting> appSettingList = catAppSettingService.list();
		List<UserSetting> userSettingList = new ArrayList<>();
		for (CatAppSetting catAppSetting : appSettingList) {
			UserSetting userSetting = new UserSetting();
			userSetting.setId(generateIdService.nextDefaultSerialNumber());
			userSetting.setSettingId(catAppSetting.getId());
			userSetting.setAccountId(userAccount.getId());
			userSetting.setCreateTime(new Date());
			if(4 == catAppSetting.getType()) {
				userSetting.setStatus(SysContants.NO);
			}
			userSetting.setStatus(SysContants.YES);
			userSettingList.add(userSetting);
			
		}
		userSettingService.saveBatch(userSettingList);
		
		// 保存用户角色
		AccountRoleMapping accountRoleMapping = new AccountRoleMapping();
		accountRoleMapping.setId(generateIdService.nextDefaultSerialNumber());
		accountRoleMapping.setRoleId(accountRole.getId());
		accountRoleMapping.setCreateTime(new Date());
		accountRoleMapping.setAccountId(accountId);
		this.accountRoleMappingService.save(accountRoleMapping);
		return 	userAccount;
	}

	@Override
	public ResponseModel<UserAccount> getUserStatus(String phone) {
		try {
			phone = AesUtils.decrypt(phone, happyCatSecurity.getAesKey());			
		}catch(Exception e) {
			ResponseModelUtils.fail("账号格式不正确", null);
		} 
		UserAccount userAccount = new UserAccount();
		userAccount.setAccountName(phone);
		Wrapper<UserAccount> queryWrapper = new QueryWrapper<UserAccount>(userAccount);
		userAccount = getOne(queryWrapper);
		UserAccount result = new UserAccount();
		if(userAccount == null) {
			result.setAccountName(phone);
			result.setStatus(SysContants.USER_STATUS_UNREGISTER);
		}else {
			result.setAccountName(phone);
			result.setStatus(userAccount.getStatus());
		}
		
		return ResponseModelUtils.success("查询成功！",result);
	}

	@Override
	public ResponseModel<UserAccount> modifyPassword(UserAccount userAccount) {
		// 查询用户是否存在
		try {
			userAccount.setAccountName(AesUtils.decrypt(userAccount.getAccountName(), happyCatSecurity.getAesKey()));
			String dePassword = AesUtils.decrypt(userAccount.getPassword(), happyCatSecurity.getAesKey());
			userAccount.setPassword(AesUtils.encrypt(dePassword, happyCatSecurity.getStageBackAesKey()));
		}catch(Exception e) {
			return ResponseModelUtils.fail("账号格式不正确", null);
		}

		UserAccount userAccountParam = new UserAccount();
		userAccountParam.setAccountName(userAccount.getAccountName());
		UserAccount userAccountResult = getAccountMappingRoleList(userAccountParam);
		
		if(userAccountResult == null) {
            //---注册用户--start
            userAccount = register(userAccount);
            //---注册用户--end
            // 保存用户登录日志
            UserLoginLog userLoginLog = new UserLoginLog();
            userLoginLog.setId(generateIdService.nextDefaultSerialNumber());
            userLoginLog.setAccountId(userAccount.getId());
            userLoginLog.setDevice(userAccount.getDevice());
            userLoginLog.setLoginType(SysContants.LOGIN_TYPE_CODE);
            userLoginLog.setCreateTime(new Date());
            userLoginLog.setLoginResult("登录成功");
            userLoginLogService.save(userLoginLog);
            //置空用户敏感信息
            userAccount.setPassword(null);
            //设置用户token
            userAccount.setToken(JwtTokenUtil.createJWT(userAccount, audience));
            userAccount.setAccountRoleList(null);
		    return ResponseModelUtils.success("设置密码成功！", userAccount);
		}else {
		    //更新密码, 不做
//            userAccountResult.setPassword(userAccount.getPassword());
//            updateById(userAccountResult);
            userAccountResult.setToken(JwtTokenUtil.createJWT(userAccount, audience));
		    return ResponseModelUtils.success("设置密码成功！", userAccountResult);
        }
//			return ResponseModelUtils.fail("账号已存在", null);


	}

	@Override
	public ResponseModel<UserAccount> resetPassword(UserAccount userAccount) {
		
		try {
			userAccount.setAccountName(AesUtils.decrypt(userAccount.getAccountName(), happyCatSecurity.getAesKey()));
			String decryptPassword = AesUtils.decrypt(userAccount.getPassword(), happyCatSecurity.getAesKey());
			if(StringUtils.isBlank(decryptPassword)) {
				return ResponseModelUtils.fail("密码不能为空", null);
			}
			userAccount.setPassword(AesUtils.encrypt(decryptPassword, happyCatSecurity.getStageBackAesKey()));
		}catch(Exception e) {
			return ResponseModelUtils.fail("账号格式不正确", null);
		}
		UserAccount userAccountParam = new UserAccount();
		userAccountParam.setAccountName(userAccount.getAccountName());
		UserAccount userAccountResult = getAccountMappingRoleList(userAccountParam);
		if(userAccountResult == null) {
			return ResponseModelUtils.fail("账号不存在", null);
		}
		userAccount.setId(userAccountResult.getId());
		updateById(userAccount);		
		userAccountResult.setToken(JwtTokenUtil.createJWT(userAccountResult, audience));
		//置空敏感信息
		userAccountResult.setAccountRoleList(null);
		userAccountResult.setPassword(null);
		return ResponseModelUtils.success("登录成功！", userAccountResult);
	}

    @Override
    public Boolean updateBalance(long accounId, double num, int type, String transId, int symbol, int experience) {
	    if(Double.compare(num, 0.0)!=1){
	        log.info("变动金额为0,无需更新...");
	        return true;
        }
	    synchronized (accounId+""){
	        //查询账户
            UserAccount account = getById(accounId);
            if(account==null || account.getStatus()==null || account.getStatus()!=1){
                log.error("用户不存在或状态不正常, accId:{}", accounId);
                throw new RuntimeException("用户不存在或状态不正常");
            }
            if(symbol==0){//支出
                if(account.getBalance()==null || account.getBalance().compareTo(num) < 0){
                    log.error("用户余额不足，当前余额:{}, 赠送所需数量:{}", account.getBalance(), num);
                    throw new RuntimeException("余额不足");
                }
                account.setBalance(NumberUtil.sub(account.getBalance().doubleValue(), num));
            }else
                account.setBalance(NumberUtil.add(account.getBalance().doubleValue(), num));

            if(experience!=0){
                account.setExp((NumberUtil.add(account.getExp()==null?"0":account.getExp()+"", experience+"")).intValue());
                //新增经验值流水
                UserExperience userExperience = new UserExperience();
                userExperience.setAccountId(accounId);
                userExperience.setCreateTime(new Date());
                userExperience.setCurrentExperience(account.getExp());
                userExperience.setExperiencePoints(experience);
                userExperience.setSource(UserExperience.GIVE_GIFT);
                userExperienceService.save(userExperience);
            }

            updateById(account);

            String text = "";
            switch (type){
                case 0:
                    text = "管理员调整";
                    break;
                case 1:
                    text = "充值";
                    break;
                case 2:
                    text = "送礼物";
                    break;
                case 3:
                    text = "开箱子";
                    break;
                case 4:
                    text = "购买商城背包物品";
                    break;
                case 5:
                    text = "订单消费";
                    break;
            }
            //新增流水
            UserBalancePetValueDetail detail = new UserBalancePetValueDetail();
            detail.setType(type);
            detail.setText(text);
            detail.setAccountId(accounId);
            detail.setAmount(num);
            detail.setCurrentAmount(account.getBalance());
            detail.setChangeTime(new Date());
            detail.setAmountType("0");
            detail.setSymbol(symbol+"");
            detail.setTrans_id(transId);
            balancePetValueDetailService.save(detail);
        }
        return true;
    }

    @Override
    public String getImUserId(Long accountId) {
        UserAccount userAccount = getById(accountId);
        if(userAccount==null || userAccount.getStatus()==null || userAccount.getStatus()!=1){
            log.error("用户不存在或状态不正常, accountId:{}", accountId);
            throw new RestApiException(R.fail(-1, "用户不存在或状态不正常"));
        }
        if(StrUtil.isBlank(userAccount.getImUserId())){
            userAccount.setImUserId(UUID.randomUUID().toString());
            updateById(userAccount);
        }
        return userAccount.getImUserId();
    }

    @Override
    public UserAccount checkUserById(long userId) {
        UserAccount userAccount = getById(userId);
        if(userAccount==null || userAccount.getStatus()==null || userAccount.getStatus()!=1){
            throw new RestApiException(R.fail("用户不存在或不可用"));
        }
        return userAccount;
    }

}
